using System;
using System.Collections.Generic;
using TrueSync;

namespace HEFramework
{
    public class Formula
    {
        public static Random random = new();


        /// <summary>
        /// 暴击
        /// </summary>
        /// <param name="_value"></param>
        /// <returns></returns>
        public static bool CTR(FP _value)
        {
            if (_value >= 100)
            {
                return true;
            }

            // 生成一个0到99（包括0和99）的随机整数
            FP roll = random.Next(100);
            return roll < (_value);
        }

        /// <summary>
        /// 格挡
        /// </summary>
        /// <param name="_atk"></param>
        /// <param name="_values"></param>
        /// <returns></returns>
        public static FP BLO(FP _atk, List<FP> _values)
        {
            if (_atk <= 0)
            {
                return 0;
            }

            FP value = 0;
            for (int i = 0; i < _values.Count; i++)
            {
                value += _values[i];
            }

            FP d = _atk - value;
            if (d <= 0)
            {
                d = 0;
            }

            return d;
        }

        /// <summary>
        /// 闪避
        /// </summary>
        /// <param name="_values"></param>
        /// <returns></returns>
        public static bool DOG(List<FP> _values)
        {
            FP roll = random.Next(100);
            return roll < (DOGV(_values));
        }

        /// <summary>
        /// 闪避率
        /// </summary>
        /// <param name="_values"></param>
        /// <returns></returns>
        public static FP DOGV(List<FP> _values)
        {
            return UnLineAdd(_values);
        }


        /// <summary>
        /// 攻击伤害
        /// </summary>
        /// <param name="_atk"></param>
        /// <param name="_def"></param>
        /// <returns></returns>
        public static FP PDG(FP _atk, FP _def)
        {
            FP result = 0;

            if (_def >= 0)
            {
                // 抗性计算
                result = (0.06 * _def) / (1 + 0.06 * _def);
            }
            else
            {
                //易伤计算
                result = (0.06 * _def) / (1 - 0.06 * _def);
            }

            return _atk * (1 - result);
        }


        /// <summary>
        /// 法术伤害
        /// </summary>
        /// <param name="_atk"></param>
        /// <param name="_values"></param>
        /// <returns></returns>
        public static FP MDG(FP _atk, List<FP> _values)
        {
            //抗性计算
            return _atk * (100 - MDEF(_values)) / 100;
        }

        /// <summary>
        /// 法抗值
        /// </summary>
        /// <param name="_values"></param>
        /// <returns></returns>
        public static FP MDEF(List<FP> _values)
        {
            return UnLineAdd(_values);
        }


        /// <summary>
        /// 最终CD
        /// </summary>
        /// <param name="_value"></param>
        /// <param name="_values"></param>
        /// <returns></returns>
        public static FP CD(FP _value, List<FP> _values)
        {
            return _value * (100 - M_ATK_SP(_values)) / 100;
        }

        /// <summary>
        /// 攻击频率（次/（毫秒））
        /// </summary>
        /// <param name="_ias">攻击速度</param>
        /// <param name="_bta">基础攻击间隔（毫秒）</param>
        /// <returns></returns>
        public static FP P_ATK_F(FP _ias, FP _bta)
        {
            if (_ias < -80)
            {
                _ias = -80;
            }

            if (_ias > 1600)
            {
                _ias = 1600;
            }

            return (1 + _ias / 100) / _bta;
        }

        /// <summary>
        /// 攻击间隔（（毫秒）/次）
        /// </summary>
        /// <param name="_ias"></param>
        /// <param name="_bta"></param>
        /// <returns></returns>
        public static FP P_ATK_AT(FP _ias, FP _bta)
        {
            return 1 / P_ATK_F(_ias, _bta);
        }

        /// <summary>
        /// 法术急速
        /// </summary>
        /// <param name="_values"></param>
        /// <returns></returns>
        public static FP M_ATK_SP(List<FP> _values)
        {
            return UnLineAdd(_values);
        }


        /// <summary>
        /// 比例
        /// </summary>
        /// <param name="_value"></param>
        /// <param name="_rate"></param>
        /// <returns></returns>
        public static FP RA(FP _value, FP _rate)
        {
            return _value * PCT(_rate);
        }

        /// <summary>
        /// 百分比（整数）->（小数）
        /// </summary>
        /// <param name="_value"></param>
        /// <returns></returns>
        public static FP PCT(FP _value)
        {
            return _value / 100;
        }

        /// <summary>
        /// 长度（厘米）-> （米）
        /// </summary>
        /// <param name="_value"></param>
        /// <returns></returns>
        public static FP LG(FP _value)
        {
            return _value / 100;
        }

        /// <summary>
        /// 时间（毫秒）-> （秒）
        /// </summary>
        /// <param name="_value"></param>
        /// <returns></returns>
        public static FP TM(FP _value)
        {
            return _value / 1000;
        }

        /// <summary>
        /// 差异变化
        /// </summary>
        /// <param name="_original"></param>
        /// <param name="_originalMax"></param>
        /// <param name="_newMax"></param>
        /// <returns></returns>
        public static FP Dif(FP _original, FP _originalMax, FP _newMax)
        {
            return _original * _newMax / _originalMax - _original;
        }


        /// <summary>
        /// 获取服装名字
        /// </summary>
        /// <param name="_name"></param>
        /// <param name="_id"></param>
        /// <returns></returns>
        public static string CN(string _name, int _id)
        {
            string[] names = _name.Split('_');
            int length = 2;
            if (names.Length != length)
            {
                return "";
            }
            else
            {
                return names[0] + "_" + _id + "_" + names[1];
            }
        }


        /// <summary>
        /// 非线性叠加
        /// </summary>
        /// <param name="_values"></param>
        /// <returns></returns>
        private static FP UnLineAdd(List<FP> _values)
        {
            if (_values.Count == 0)
            {
                return 0;
            }

            FP add = 1;

            foreach (var value in _values)
            {
                if (value >= 100)
                {
                    return 100;
                }

                add *= (1 - value / 100);
            }

            return (1 - add) * 100;
        }
    }
}